package finman.database;
import java.util.Date;
/**
 * Encapsulates contract data and functionality.
 * There are following abilities:
 * 1)create (creates contract, it's just data structure with information);
 * 2)sign;
 * 3)extend (extends the term of the signed contract only)
 * 4)ripUp (marks it as ripped up before the appointed time)
 * When contract is ripped its finalDate equals null.
 */
public class Contract {

	private String number;

	private Organization organization;	
	private Valuta valuta;
	private Long money;
 	private String subject;

    private boolean signed = false;
    private Date registrationDate, finalDate;
    private boolean ripped = false;

    /**
     * Creates new contract with specified number, organization, currency(valuta), and subject.
     */
    public Contract(String number, Organization organization, Valuta valuta, Long money, String subject) {
        this.number = number;
        this.organization = organization;
        this.valuta = valuta;
        this.money = money;
        this.subject = subject;
    }

    /**
     * Marks this contract as signed and specifies registration and final dates.
     */
    public void sign(Date start, Date end) {
        signed = true;
        registrationDate = start;
        finalDate = end;
    }

    /**
     * Extends a term of this contract to specified new date.
     * if the new date is earlier than an old one, a IllegalArgumentException will be thrown.
     */
    public void extend(Date newFinalDate) {
        if(finalDate.after(newFinalDate)) throw new
                IllegalArgumentException("new date has to be later than current finalDate");
        finalDate = newFinalDate;
    }

    /**
     * Rips up this contract. if contract not signed method does nothing.
     */
    public void ripUp() {
        if(signed) {
            finalDate = null;
            ripped = true;
        }
    }

    /**
     * Returns a date when contract was signed.
     */
    public Date getRegistrationDate() {
        return registrationDate;
    }

    /**
     * Returns a date to which contract is valid.
     */
    public Date getFinalDate() {
        return finalDate;
    }

    /**
     * Checks whether this contract is signed.
     */
    public boolean isSigned() {
        return signed;
    }

    /**
     * Checks whether this contract was signed and then ripped up.
     */
    public boolean isRipped() {
        return ripped;
    }

    @Override
    public int hashCode() {
        int hashCode = 0;
        if (number != null) {
            hashCode += number.hashCode();
        }
        if (organization != null) {
            hashCode += organization.hashCode();
        }
        if (valuta != null) {
            hashCode += valuta.hashCode();
        }
        if (money != null) {
            hashCode += money.hashCode();
        }
        if (subject != null) {
            hashCode += subject.hashCode();
        }
        return hashCode;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Contract)) {
            return false;
        }
        Contract contract = (Contract) obj;
        // check if 'obj' hold an non-null field that is null in this one!
        if (
                ((number == null)&&(contract.number != null)) ||
                ((organization == null)&&(contract.organization  != null)) ||
                ((valuta == null)&&(contract.valuta != null)) ||
                ((money == null)&&(contract.money != null)) ||
                ((subject == null)&&(contract.subject != null))
           )
        {
            return false;
        }

        // whether all field are equal ?
        if ((number != null) && (!number.equals(contract.number))) {
            return false;
        }
        if ((organization != null) && (!organization.equals(contract.organization))) {
            return false;
        }
        if ((valuta != null) && (! valuta.equals(contract.valuta))) {
            return false;
        }
        if ((money != null) && (! money.equals(contract.money))) {
            return false;
        }
        if ((subject != null) && (! subject.equals(contract.subject))) {
            return false;
        }
        return true;

    }

    @Override
    public String toString() {
        return String.format("Contract(%1s)", number);
    }
}